#pragma once
#include<iostream>
#include<string>
#include<functional>
#include<pthread.h>

using namespace std;

//typedef function<void()> func_t
template<class T>
using func_t=function<void(T&)>;

template<class T>
class Thread
{
public:
    Thread(const string& threadname,func_t<T> func,T& data)
    :_tid(0),_threadname(threadname),_isrunning(false),_func(func),_data(data)
    {}

    static void* Threadroutine(void* args)//类内成员方法，其第一个参数是this指针，所以会导致编译错误
   //这里使用static，让Thraedroutine成为类的方法，
    {
        (void)args;//仅仅是为了消除警告，变量未使用

        Thread* ts=static_cast<Thread*>(args);
        ts->_func(ts->_data);
        return nullptr;
    }

    bool Start()
    {
        int n=pthread_create(&_tid,nullptr,Threadroutine,this);//把当前对象传递给线程执行的方法
        if(n==0)
        {
            _isrunning=true;
            return true;
        }
        else return false;
    }

    bool Join()
    {
        if(!_isrunning)return true;
        int n=pthread_join(_tid,nullptr);
        if(n==0)
        {
            _isrunning=false;
            return true;
        }
        return false;
    }

    bool Isrunning()
    {
        return _isrunning;
    }

    string Threadname()
    {
        return _threadname;
    }
private:
    pthread_t _tid;
    string _threadname;
    bool _isrunning;
    func_t<T> _func;
    T _data;
};
